#pragma once
#include <iostream>
#include <memory>
#include <unistd.h>
#include <sys/select.h>

#include "Log.hpp"
#include "Socket.hpp"

const int defaultbacklog = 5;
const int num = sizeof(fd_set) * 8;

class SelectService
{
private:
    void ReadHandlerService(fd_set &rfds)
    {
        for (int i = 0; i < num; i++)
        {
            if (_rfds_array[i])
            {
                int fd = _rfds_array[i]->GetSockFd();
                if (!FD_ISSET(fd, &rfds))
                {
                    continue;
                }

                if (fd == _listensock->GetSockFd())
                {
                    string ip;
                    uint16_t port;
                    Socket *newsock = _listensock->BuildServerSock(&ip, &port);
                    if (!newsock)
                    {
                        LOG(Abnormal, "获取文件描述符失败\n");
                    }

                    int pos = 0;
                    for (; pos < num; pos++)
                    {
                        if (!_rfds_array[pos])
                        {
                            _rfds_array[pos] = newsock;
                            LOG(Info, "连接建立成功，文件描述符：%d\n", newsock->GetSockFd());
                            break;
                        }
                    }

                    if (pos == num)
                    {
                        LOG(Abnormal, "文件描述符数量超出上限\n");
                        newsock->GetSockFd();
                        delete newsock;
                    }
                }
                else
                {
                    string buffer;
                    bool ret = _rfds_array[i]->Recv(buffer, 1024);
                    if (ret)
                    {
                        cout << "client say# " << buffer << endl;
                    }
                    else
                    {
                        cout << "关闭连接：" << fd << endl;
                        _rfds_array[i]->CloseSockFd();
                        delete _rfds_array[i];
                        _rfds_array[i] = nullptr;
                    }
                }
            }
        }
        // if (FD_ISSET(_listensock->GetSockFd(), &rfds))
        // {
        //     // string ip;
        //     // uint16_t port;
        //     // Socket *newsock = _listensock->BuildServerSock(&ip, &port);
        //     // if (!newsock)
        //     // {
        //     //     LOG(Abnormal, "获取文件描述符失败\n");
        //     // }

        //     // int pos = 0;
        //     // for (; pos < num; pos++)
        //     // {
        //     //     if (!_rfds_array[pos])
        //     //     {
        //     //         _rfds_array[pos] = newsock;
        //     //         LOG(Info, "连接建立成功，文件描述符：%d\n", newsock->GetSockFd());
        //     //         break;
        //     //     }
        //     // }

        //     // if (pos == num)
        //     // {

        //     //     LOG(Abnormal, "文件描述符数量超出上限\n");
        //     //     newsock->GetSockFd();
        //     //     delete newsock;
        //     // }
        // }
        // else
        // {
        // }
    }

public:
    SelectService(uint16_t port, int backlog = defaultbacklog) : _port(port), _backlog(backlog), _isrunning(false)
    {
    }

    void Init()
    {
        _listensock = make_unique<TcpSocket>();
        _listensock->BuildListenSock(_port, _backlog);
        for (int i = 0; i < num; i++)
        {
            _rfds_array[i] = nullptr;
        }

        _rfds_array[0] = _listensock.get();
    }

    void Loop()
    {
        _isrunning = true;

        while (_isrunning)
        {
            fd_set rfds;
            FD_ZERO(&rfds);
            int max_fd = -1;
            for (int i = 0; i < num; i++)
            {
                if (_rfds_array[i])
                {
                    FD_SET(_rfds_array[i]->GetSockFd(), &rfds);
                    max_fd = max(_rfds_array[i]->GetSockFd(), max_fd);
                }
            }
            PrintDebug();

            struct timeval tm = {1, 0};
            int n = select(max_fd + 1, &rfds, nullptr, nullptr, &tm);
            switch (n)
            {
            case 0:
                cout << "没有读条件就绪" << endl;
                break;
            case -1:
                cout << "出现错误" << endl;
                break;
            default:
            {
                LOG(Info, "读条件就绪\n");
                ReadHandlerService(rfds);
                break;
            }
            }
        }
        _isrunning = false;
    }

    void PrintDebug()
    {
        cout << "已经建立连接的文件描述符：";
        for (int i = 0; i < num; i++)
        {
            if (_rfds_array[i])
            {
                cout << _rfds_array[i]->GetSockFd() << " ";
            }
        }
        cout << endl;
    }

    void Stop()
    {
    }

    ~SelectService()
    {
        _listensock->CloseSockFd();
    }

private:
    bool _isrunning;

    uint16_t _port;
    int _backlog;
    unique_ptr<Socket> _listensock;

    Socket *_rfds_array[num];
};